package ee.android.kinokavad.activities;

import java.util.List;

import org.joda.time.DateTime;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.HeaderViewListAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.MenuItem;
import com.sherlock.navigationdrawer.compat.SherlockActionBarDrawerToggle;

import ee.android.kinokavad.App;
import ee.android.kinokavad.R;
import ee.android.kinokavad.adapters.NavigationAdapter;
import ee.android.kinokavad.data.Cinema;
import ee.android.kinokavad.data.DrawerItem;
import ee.android.kinokavad.data.Session;
import ee.android.kinokavad.fragments.CinemasFragment;
import ee.android.kinokavad.fragments.MainFragmentKinoKavad;
import ee.android.kinokavad.fragments.MoviesFragment;
import ee.android.kinokavad.interfaces.OnMovieClickListener;
import ee.android.kinokavad.utils.LogUtils;
import ee.android.kinokavad.utils.NetworkUtils;

public class KinoKavadActivity extends SherlockFragmentActivity implements OnMovieClickListener, OnClickListener {

	private static final String TAG = KinoKavadActivity.class.getSimpleName();
	private App kinokavad;
	private ProgressDialog mProgressDialog;

	private DrawerLayout mDrawerLayout;
	private SherlockActionBarDrawerToggle mDrawerToggle;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.kinokavad);
		kinokavad = (App) getApplicationContext();
		initDrawer();

		if (!getIntent().getBooleanExtra("reload", false)) {
			deleteOldData();
		}

		initData(savedInstanceState);
	}

	@Override
	protected void onStart() {
		super.onStart();
		LogUtils.onStartSession(this);
	}

	@Override
	protected void onStop() {
		super.onStop();
		LogUtils.onEndSession(this);
	}

	private void initData(Bundle savedInstanceState) {

		kinokavad.getDataController().open();
		long cinemaCount = kinokavad.getDataController().getCinemaCount();
		long sessionCount = kinokavad.getDataController().getSessionCount();
		if (App.LOCAL_LOG)
			Log.d(TAG, "Loaded cinemas: " + cinemaCount + " - sessions: " + sessionCount);
		if (cinemaCount == 0 || sessionCount == 0) {
			if (NetworkUtils.isNetworkAvailable(this)) {
				new SyncTask().execute(cinemaCount, sessionCount);
			} else {
				NetworkUtils.showNoNetworkConnectionDialog(this);
			}
		}
		kinokavad.getDataController().closeRequest();

		if (sessionCount != 0) {
			getSupportActionBar().setHomeButtonEnabled(true);
			findViewById(R.id.kinokavadEmptyView).setVisibility(View.GONE);
			if (savedInstanceState == null) {
				replaceFragment(this, MainFragmentKinoKavad.newInstance(null), false, false);
			}
		} else {
			getSupportActionBar().setHomeButtonEnabled(false);
			findViewById(R.id.kinokavadEmptyView).setOnClickListener(this);
			findViewById(R.id.kinokavadEmptyView).setVisibility(View.VISIBLE);
		}

	}

	private void deleteOldData() {
		kinokavad.getDataController().open();
		kinokavad.getDataController().deleteOldSessions();
		kinokavad.getDataController().deleteOldMovies();
		kinokavad.getDataController().closeRequest();
	}

	private void deleteAllSessions() {
		kinokavad.getDataController().open();
		kinokavad.getDataController().deleteAllSessions();
		kinokavad.getDataController().closeRequest();
	}

	private void showProgressDialog() {
		mProgressDialog = ProgressDialog.show(this, "Andmete tõmbamine", "Filmide, seansside ja kinode laadimine");
	}

	private void dismissProgressDialog() {
		if (mProgressDialog != null)
			mProgressDialog.dismiss();
	}

	private class SyncTask extends AsyncTask<Long, Integer, long[]> {

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			showProgressDialog();
		}

		@Override
		protected long[] doInBackground(Long ... params) {

			long cinemasCount = params[0];
			long sessionCount = params[1];

			if (cinemasCount == 0) {
				List<Cinema> cinemas = NetworkUtils.downloadAllCinemas(KinoKavadActivity.this);
				for (Cinema cinema : cinemas) {
					kinokavad.getDataController().addCinemaToDatabase(cinema);
				}
				cinemasCount = cinemas.size();
			}

			if (sessionCount == 0) {
				List<Session> sessions = NetworkUtils.downloadAndSaveAllSessionsAndMovies(
						KinoKavadActivity.this, DateTime.now(), DateTime.now().plusDays(7));
				sessionCount = sessions.size();
			}
			if (App.LOCAL_LOG)
				Log.d(TAG, "Downloaded cinemas: " + cinemasCount + " - sessions: " + sessionCount);

			return new long [] {cinemasCount, sessionCount};
		}

		@Override
		protected void onPostExecute(long[] result) {
			super.onPostExecute(result);
			dismissProgressDialog();
			if (result[0] == 0 || result[1] == 0) {
				Toast.makeText(KinoKavadActivity.this, "Andmete laadimine ebaõnnestus, palun proovige hiljem uuesti.", Toast.LENGTH_LONG).show();
			} else {
				getSupportActionBar().setHomeButtonEnabled(true);
				findViewById(R.id.kinokavadEmptyView).setVisibility(View.GONE);
				replaceFragment(KinoKavadActivity.this, MainFragmentKinoKavad.newInstance(null), false, false);
			}
		}

	}


	public void handleMoviesClick(boolean fromDrawer) {
		replaceFragment(this, MoviesFragment.newInstance(null), false, fromDrawer);
	}

	public void handleCinemasClick(boolean fromDrawer) {
		replaceFragment(this, CinemasFragment.newInstance(null), false, fromDrawer);
	}

	public void handleSessionsClick(boolean fromDrawer) {
		replaceFragment(this, MainFragmentKinoKavad.newInstance(null), false, fromDrawer);		
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		if (mDrawerToggle.onOptionsItemSelected(item)) {
			return true;
		}

		switch (item.getItemId()) {
		case R.id.menuMoviesFragment:
			handleMoviesClick(false);
			break;
		case R.id.menuCinemasFragment:
			handleCinemasClick(false);
			break;
		case R.id.menuSessionsFragment:
			handleSessionsClick(false);
			break;
		case R.id.menuRefresh:
			handleReloadClick();
			break;
		}

		return super.onOptionsItemSelected(item);
	}

	private void handleReloadClick() {
		reload(this);
	}
	
	public static void reload(KinoKavadActivity context) {
		context.deleteAllSessions();
		context.finish();
		Intent i = new Intent(context, KinoKavadActivity.class);
		i.putExtra("reload", true);
		context.startActivity(i);
	}
	
	

	public static void replaceFragment(Context context, Fragment fragment, boolean addToBackStack, boolean fromDrawer) {

		FragmentManager fm = ((FragmentActivity) context).getSupportFragmentManager();

		Fragment current = fm.findFragmentById(R.id.content);
		String tag = fragment.getClass().getSimpleName();

		if (current != null && current.getTag().equals(tag)) {
			if (fromDrawer) {
				closeDrawer(context);
			}
			return;
		}

		if (fromDrawer) {
			fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
		}

		FragmentTransaction transaction = fm .beginTransaction()
				.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
				.replace(R.id.content, fragment, tag);
		if (addToBackStack) {
			transaction.addToBackStack(null);
		}

		if (fromDrawer) {
			closeDrawer(context);
		}

		transaction.commit();

		updateDrawer(fm, tag);

	}

	private static void closeDrawer(Context context) {
		final DrawerLayout drawer = (DrawerLayout) ((FragmentActivity) context).findViewById(R.id.drawer_layout);
		if (drawer != null)
			drawer.postDelayed(new Runnable() {

				@Override
				public void run() {
					drawer.closeDrawer(GravityCompat.START);
				}           
			}, 50);
	}

	private static void updateDrawer(FragmentManager fm, String tag) {

		ListView drawerList = (ListView) fm
				.findFragmentById(R.id.left_drawer).getView().findViewById(R.id.drawerList);

		NavigationAdapter adapter = (NavigationAdapter)((HeaderViewListAdapter) drawerList.getAdapter()).getWrappedAdapter();

		int lastSelection = -1;
		boolean selected = false;
		for (int i = 0; i < adapter.getCount(); i++) {
			DrawerItem item = adapter.getItem(i);
			if (item.isSelected() && lastSelection == -1) lastSelection = i;
			if (item.getTag().equals(tag)) {
				item.setSelected(true);
				selected = true;
			} else {
				item.setSelected(false);
			}
		}
		if (!selected && lastSelection != -1) {
			adapter.getItem(lastSelection).setSelected(true);
		}
		adapter.notifyDataSetChanged();
	}

	@Override
	protected void onPostCreate(Bundle savedInstanceState) {
		super.onPostCreate(savedInstanceState);
		// Sync the toggle state after onRestoreInstanceState has occurred.
		if (mDrawerToggle != null)
			mDrawerToggle.syncState();
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		mDrawerToggle.onConfigurationChanged(newConfig);
	}

	private void initDrawer() {

		mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
		mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
		mDrawerToggle = new SherlockActionBarDrawerToggle(
				this,                  /* host Activity */
				mDrawerLayout,         /* DrawerLayout object */
				R.drawable.ic_navigation_drawer,  /* nav drawer icon to replace 'Up' caret */
				R.string.drawer_open,  /* "open drawer" description */
				R.string.drawer_close  /* "close drawer" description */
				) {

			/** Called when a drawer has settled in a completely closed state. */
			public void onDrawerClosed(View view) {}
			/** Called when a drawer has settled in a completely open state. */
			public void onDrawerOpened(View drawerView) {}
		};

		// Set the drawer toggle as the DrawerListener
		mDrawerLayout.setDrawerListener(mDrawerToggle);

	}

	@Override
	public void onMovieClicked(long movieId) {
		Intent intent = new Intent(this, MovieSummaryActivity.class);
		intent.putExtra("movieId", movieId);
		intent.putExtra("actionBarSubtitle", getSupportActionBar().getSubtitle());
		startActivity(intent);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.kinokavadEmptyView:
			handleEmptyViewClick();
			break;

		default:
			break;
		}
	}

	private void handleEmptyViewClick() {
		if (NetworkUtils.isNetworkAvailable(this)) {
			initData(null);	
		} else {
			NetworkUtils.showNoNetworkConnectionDialog(this);
		}
	}



}
